package cn.com.zonesion.rfiddemo.activity;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTransaction;
import android.view.MotionEvent;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RadioGroup;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import com.x210.android.serialPortSample.SerialPort;
import com.x210.android.serialPortSample.SerialPortFinder;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.ref.WeakReference;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;
import cn.com.zonesion.rfiddemo.R;
import cn.com.zonesion.rfiddemo.adapter.InstructionListAdapter;
import cn.com.zonesion.rfiddemo.base.BaseFragment;
import cn.com.zonesion.rfiddemo.bean.InstructionBean;
import cn.com.zonesion.rfiddemo.fragment.microwavefragment.MicrowaveLabelFragmet;
import cn.com.zonesion.rfiddemo.fragment.microwavefragment.MicrowaveReadFragment;

/**
 * Created by Administrator on 2018/4/23.
 */

public class MicrowaveMainActivity extends FragmentActivity implements View.OnTouchListener{

    @BindView(R.id.rg_bottom_tag_microwave)
    RadioGroup rgBottomTag;
    /**
     * 展示当前系统时间
     */
    @BindView(R.id.tv_current_time)
    TextView tvCurrentTimeIc;
    @BindView(R.id.btn_connection)
    Button btnConnection;
    @BindView(R.id.image_link_icon)
    ImageView imageLinkIcon;
    @BindView(R.id.listView_debugging_microwave)
    ListView listView;
    private int position = 0;
    @BindView(R.id.btn_slide_data_microwave)
    Button btnSlideData;
    /**
     * 缓存的Fragemnt或者上次显示的Fragment
     */
    private Fragment tempFragemnt;
    /**
     * 装多个Fragment的实例集合
     */
    private ArrayList<BaseFragment> fragments;
    /**
     * 波特率数组，用来存放常用波特率
     */
    private String[] baudrateArray;
    /**
     * 存放串口名称
     */
    private List<String> driverList;
    /**
     * 串口路径
     */
    private File serialPath;
    /**
     * 串口对应的波特率
     */
    private int baudrate;

    /**
     * AttendanceHandler发送消息定时获取系统时间的标识
     */
    private static final int GET_SYSTEM_TIME = 0;
    /**
     * AttendanceHandler发送消息定时检测获取串口的标识符
     */
    private static final int CHECK_SERIAlPORT = 1;
    /**
     * AttendanceHandler发送消息定时查询卡号的标识
     */
    private static final int QUERY_CARD_NUM = 2;

    /**
     * 用来存放InstructionBean对象的ArrayList
     */
    private ArrayList<InstructionBean> microwaveInstructionBeanArrayList;
    /**
     * ListView的适配器对象
     */
    private InstructionListAdapter adapter;
    /**
     * 标识是否向用户提示串口是否连接成功
     */
    private boolean hasTipConnection = false;
    /**
     * 串口对象
     */
    private SerialPort serialPort;
    /**
     * 是否启动了读取数据的线程
     */
    private boolean hasStartThread;
    /**
     * 该线程用来读取数据
     */
    private Thread readThread;
    /**
     * 用来标识串口是否连接成功
     */
    private boolean serialConnectSus = false;
    /**
     * 记录无卡指令出现的次数
     */
    private static  int NO_CARD = 0;
    /**
     * AttendanceHandler主要用来做一些定时的工作
     */
    private AttendanceHandler handler;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main_microwave);
        ButterKnife.bind(this);//将ButterKnife和IcMainActivity绑定
        /**
         * 初始化Fragment
         */
        initFragment();
        //设置RadioGroup的监听
        initListener();
        initView();
        handler.sendEmptyMessage(CHECK_SERIAlPORT);
    }

    private void initFragment() {
        fragments = new ArrayList<>();
        fragments.add(new MicrowaveLabelFragmet());
        fragments.add(new MicrowaveReadFragment());
    }

    private void initListener(){
        rgBottomTag.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                switch (checkedId) {
                    case  R.id.btn_basics_microwave://标签
                        position = 0;
                        break;
                    case  R.id.btn_application_microwave://阅读器
                        position = 1;
                        break;
                    default:
                        position = 0;
                        break;

                }
                //根据位置取不同的Fragment
                BaseFragment baseFragment = getFragment(position);
                switchFragment(tempFragemnt, baseFragment);
            }
        });
        rgBottomTag.check(R.id.btn_basics_microwave);
    }
    private BaseFragment getFragment(int position) {
        if (fragments != null && fragments.size() > 0) {
            BaseFragment baseFragment = fragments.get(position);
            return baseFragment;
        }
        return null;
    }
    private void switchFragment(Fragment fromFragment, BaseFragment nextFragment) {
        if (tempFragemnt != nextFragment) {
            tempFragemnt = nextFragment;
            if (nextFragment != null) {
                FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
                //判断nextFragment是否添加
                if (!nextFragment.isAdded()) {
                    //隐藏当前Fragment
                    if (fromFragment != null) {
                        transaction.hide(fromFragment);
                    }
                    //添加Fragment
                    transaction.add(R.id.content_fragment_microwave, nextFragment).commit();
                } else {
                    //隐藏当前Fragment
                    if (fromFragment != null) {
                        transaction.hide(fromFragment);
                    }
                    transaction.show(nextFragment).commit();
                }
            }
        }
    }

    private void initView() {
//        new TimeThread().start();
        microwaveInstructionBeanArrayList = new ArrayList<>();
        adapter = new InstructionListAdapter(this,microwaveInstructionBeanArrayList);
        listView.setAdapter(adapter);
        baudrateArray = getResources().getStringArray(R.array.baudrate);
        driverList = new ArrayList<String>();
        handler = new AttendanceHandler(this);
        //为btnConnection注册单击事件
        btnConnection.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                /**
                 * 首先得到按钮上的文本 如果是"连接串口" 则点击 该按钮连接串口 并将按钮上的文本改为"关闭串口"
                 * 并开启读取数据的线程 发送消息查询卡号
                 */
                if(btnConnection.getText().toString().equals("连接串口")) {
                    showOpenTheSerialPort("串口设置");
                    /**
                     * 如果按钮文本为"关闭串口" 点击之后 则将文本置为"连接串口" 并将界面上的文本框所有数据以及全局变量恢复为初始值
                     * 调用串口的close()方法关闭串口
                     */
                }else if(btnConnection.getText().toString().equals("关闭串口")) {
                    btnConnection.setText("连接串口");
                    imageLinkIcon.setBackgroundResource(R.drawable.to_break_off);
                }
            }
        });
        //为btnSlideData注册点击事件
        btnSlideData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(btnSlideData.getText().toString().equals("停止滑动数据")){
                    btnSlideData.setText("开启滑动数据");
                } else if(btnSlideData.getText().toString().equals("开启滑动数据")){
                    btnSlideData.setText("停止滑动数据");
                }
            }
        });
    }
    private void showOpenTheSerialPort(String title){
        View view = View.inflate(MicrowaveMainActivity.this,R.layout.activity_seria_iport_picker,null);
        //找到布局文件中的控件
        final Spinner ttySpinner = view.findViewById(R.id.tty_spinner);
        final Spinner ttyBaudrate = view.findViewById(R.id.tty_baudrate);
        ttySpinner.setAdapter(new ArrayAdapter<>(getApplicationContext(),R.layout.spinner_layout,R.id.textView,driverList));
        ttyBaudrate.setAdapter(new ArrayAdapter<>(getApplicationContext(),R.layout.spinner_layout,R.id.textView,baudrateArray));
        /*
         * 开启一个线程来获取当前可用的串口路径
         */
        new Thread(){
            public void run(){
                String[] driverVector = new SerialPortFinder().getAllDevicesPath();//该方法用来获取可用的串口路径
                driverList.addAll(Arrays.asList(driverVector));//将获取到的串口路径已字符串的形式添加进driverList里
            }
        }.start();
        //为ttySpinner设置适配器
        ttySpinner.setAdapter(new ArrayAdapter<>(getApplicationContext(),R.layout.spinner_layout,R.id.textView,driverList));
        ttySpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> adapterView, View view, int position, long id) {
                serialPath = new File(driverList.get(position));
            }

            @Override
            public void onNothingSelected(AdapterView<?> adapterView) {}
        });
        //为ttyBaudrate注册监听事件
        ttyBaudrate.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> adapterView, View view, int position, long id) {
                baudrate = Integer.parseInt(baudrateArray[position]);
            }

            @Override
            public void onNothingSelected(AdapterView<?> adapterView) {}
        });
        ttyBaudrate.setSelection(10,true);
        new AlertDialog.Builder(this)
                .setTitle(title)//给AlertDialog设置对应的标题
                .setView(view)//给AlertDialog设置对应的布局
                .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        hasTipConnection = false;
                        if (serialPort == null) {
                            try {
                                serialPort = new SerialPort(serialPath, baudrate);
                                btnConnection.setText("关闭串口");
                                imageLinkIcon.setBackgroundResource(R.drawable.to_break_off);
                                if(!hasStartThread) {
                                    if (readThread == null) {
                                        hasStartThread = true;
                                        readThread = new Thread(new ReadThread());
                                        readThread.start();//开启读取数据的线程
                                    }
                                }
                                handler.sendEmptyMessage(QUERY_CARD_NUM);//发送消息查询125K卡号
                            } catch (IOException | SecurityException e) {
                                /**
                                 * 串口对象创建出现异常 则提示用户 并将文本重新设为"连接串口"
                                 * 将serialPort和hasStartThread置为原始值 以便能够重新连接串口
                                 */
                                e.printStackTrace();
                                Toast.makeText(getApplicationContext(), "串口对象创建异常，请检查串口或波特率是否正确,并重新连接", Toast.LENGTH_SHORT).show();
                                btnConnection.setText("连接串口");
                                imageLinkIcon.setBackgroundResource(R.drawable.link);
                                serialPort = null;
                                hasStartThread = false;
                            }

                        }
                    }
                })
                .setNegativeButton("取消",null)
                .show();
    }

    //该线程负责读取串口发来的数据
    private class ReadThread implements Runnable{

        @Override
        public void run() {
            String str;
            InputStream inputStream = serialPort.getInputStream();
            byte[] receive = new byte[25];
            try {
                int ret = 0, offset = 0;
                while (hasStartThread && (ret = inputStream.read(receive, offset, 25 - offset)) != -1) {
                    offset += ret;
                    if ((receive[0] & 0xff) == 0xCD && (receive[1] & 0xff) == 0xDC) {
                        serialConnectSus = true;
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                if(!hasTipConnection) {
                                    //串口有数据返回的时候 提示用户"串口连接成功"
                                    Toast.makeText(getApplicationContext(), "串口连接成功", Toast.LENGTH_SHORT).show();
                                    hasTipConnection = true;
                                }
                            }
                        });
//                        if (offset > 5) {
//                            int pkglen = receive[4] + 6;
//                            if (pkglen <= offset) {
//                                if (pkglen > 0) {
//                                    byte[] pkg = new byte[pkglen];
//                                    System.arraycopy(receive, 0, pkg, 0, pkglen);
//                                    str = MicrowaveMainActivity.byte2HexStr(pkg);//将串口返回的数据转化为16进制字符串
//                                    String[] result = str.split(" ");//将转换后的十六进制字符串以空格进行split
//                                    final String finalStr = str;
//
//                                    if(result.length == 11){//如果数据的长度为11 表明这条指令中有卡号的数据
//                                        runOnUiThread(new Runnable() {
//                                            @Override
//                                            public void run() {
//                                                // 125
//                                                updateInstructionData("串口返回<<--: " + finalStr,"有卡");
//                                            }
//                                        });
//
//                                        MicrowaveMainActivity.NO_CARD = 0;//清0，表示有卡
//                                        final String card = result[5] + result[6] + result[7] + result[8] + result[9];//该指令的下标为5、6、7、8和9组合起来就是卡号的数据
//
//                                    }else{
//                                        runOnUiThread(new Runnable() {
//                                            @Override
//                                            public void run() {
//                                                updateInstructionData("串口<<--: " + finalStr,"无卡");
//                                            }
//                                        });
//                                        MicrowaveMainActivity.NO_CARD  += 1;
//                                    }
//                                    System.out.println(str);
//                                    int left = offset - pkglen;
//                                    if (left > 0) {
//                                        System.arraycopy(receive, pkglen, receive, 0, left);
//                                    }
//                                    offset = left;
//                                }
//                            }
//                        }
                    } else {
                        offset = 0;
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
                hasStartThread = false;
            }
        }
    }

    //该方法用于发生查询900M卡的指令
    private void dataDeal() {
        if (serialPort != null) {
            OutputStream outputStream = serialPort.getOutputStream();
            try {
                byte[] dat = new byte[]{(byte) 0xab, (byte) 0xba, 0x00, 0x15, 0x00, 0x15};
                outputStream.write(dat);
                outputStream.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
//    private void updateInstructionData(String instruction,String role){
//        microwaveInstructionBeanArrayList.add(new InstructionBean(instruction,role));
//        adapter.notifyDataSetChanged();//更新ListView数据
//        if(btnSlideData.getText().toString().equals("停止滑动数据")){
//            listView.setSelection(listView.getCount() - 1);
//        }
//        if(btnSlideData.getText().toString().equals("开启滑动数据")){
//            listView.setSelection(-1);
//        }
//    }

    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        return false;
    }

    /**
     * bytes转换成十六进制字符串
     * @param b byte数组
     * @return String 每个Byte值之间空格分隔
     */
    public static String byte2HexStr(byte[] b)
    {
        String stmp="";
        StringBuilder sb = new StringBuilder("");
        for (int n=0;n<b.length;n++)
        {
            stmp = Integer.toHexString(b[n] & 0xFF);
            sb.append((stmp.length()==1)? "0"+stmp : stmp);
            sb.append(" ");
        }
        return sb.toString().toUpperCase().trim();
    }
    static class AttendanceHandler extends Handler{
        //创建弱引用，防止内存泄露
        private WeakReference<MicrowaveMainActivity> reference;

        AttendanceHandler(MicrowaveMainActivity mainActivity){
            //在构造方法中对reference初始化
            reference = new WeakReference<>(mainActivity);
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case  MicrowaveMainActivity.GET_SYSTEM_TIME:
                    if (reference.get() != null) {
                        reference.get().tvCurrentTimeIc.setText(new SimpleDateFormat("yyyy年MM月dd日 HH:mm").format(new Date(System.currentTimeMillis())));
                    }
                    removeMessages(MicrowaveMainActivity.GET_SYSTEM_TIME);
                    sendEmptyMessageDelayed(MicrowaveMainActivity.GET_SYSTEM_TIME, 1000);
                    break;
                case  MicrowaveMainActivity.CHECK_SERIAlPORT:
                    if(reference.get() != null) {
                        String[] driverVector = new SerialPortFinder().getAllDevicesPath();
                        reference.get().driverList.clear();
                        reference.get().driverList.add("请选择串口");
                        reference.get().driverList.addAll(Arrays.asList(driverVector));
                    }
//                    removeMessages(MicrowaveMainActivity.CHECK_SERIAlPORT);
//                    sendEmptyMessageDelayed(MicrowaveMainActivity.CHECK_SERIAlPORT,3000);
                    break;

                case  MicrowaveMainActivity.QUERY_CARD_NUM:
                    if(reference.get()!=null) {
                        reference.get().dataDeal();
                        if(reference.get().serialPort != null) {
                            if(reference.get().serialConnectSus) {
//                                byte[] dat = new byte[]{(byte) 0xab, (byte) 0xba, 0x00, 0x15, 0x00, 0x15};
//                                reference.get().updateInstructionData("串口主动发出-->>:" + IdMainActivity.byte2HexStr(dat), "读卡命令");
                            }
                        }
                    }
                    removeMessages(MicrowaveMainActivity.QUERY_CARD_NUM);
                    sendEmptyMessageDelayed(MicrowaveMainActivity.QUERY_CARD_NUM, 1000);
                    break;
            }
        }
    }
}
